/*
 * CConfig.h
 *
 *  Created on: 2011-11-18
 *      Author: Owner
 */

#ifndef CCONFIG_H_
#define CCONFIG_H_
#include "Lock.h"
#include "string.h"
#include "tinyxml.h"

#include <list>
#include <map>
#include <string>

using namespace std;

class CMyConfig2 {
public:
    CMyConfig2();
    CMyConfig2(const char *pszConfigFile);
    virtual ~CMyConfig2();

    void LoadConfig(const char *pszConfig) {
        TiXmlDocument doc;
        if (!doc.LoadFile(pszConfig)) {
            printf("load config.xml failed\n");
        }

        TiXmlElement *r = doc.RootElement();
        if (r == NULL) {
            return;
        }

        TiXmlElement *r2 = r->FirstChildElement("ConnectConfig");
        if (r2 == NULL) {
            return;
        }

        TiXmlElement *b = r2->FirstChildElement("BrokerID");
        if (b != NULL) {
            const char *psz = b->Attribute("name");
            if (psz != NULL) {
                strcpy(m_cBroker, psz);
            } else {
                m_cBroker[0] = '\0';
            }
        }

        // add new
        TiXmlElement *AppID = r2->FirstChildElement("AppID");
        if (AppID != NULL) {
            const char *psz = AppID->Attribute("name");
            if (psz != NULL) {
                strcpy(m_pszAppID, psz);
            } else {
                m_pszAppID[0] = '\0';
            }
        }

        TiXmlElement *AuthCode = r2->FirstChildElement("AuthCode");
        if (AuthCode != NULL) {
            const char *psz = AuthCode->Attribute("name");
            if (psz != NULL) {
                strcpy(m_pszAuthCode, psz);
            } else {
                m_pszAuthCode[0] = '\0';
            }
        }

        TiXmlElement *e_userID = r2->FirstChildElement("UserID");
        if (e_userID != NULL) {
            const char *psz = e_userID->Attribute("name");
            if (psz != NULL) {
                strcpy(m_cUser, psz);
            } else {
                m_cUser[0] = '\0';
            }
        }

        TiXmlElement *e_Password = r2->FirstChildElement("Password");
        if (e_Password != NULL) {
            const char *psz = e_Password->Attribute("name");
            if (psz != NULL) {
                strcpy(m_cPassword, psz);
            } else {
                m_cPassword[0] = '\0';
            }
        }

        TiXmlElement *e_Invest = r2->FirstChildElement("InvestorID");
        if (e_Invest != NULL) {
            const char *psz = e_Invest->Attribute("name");
            if (psz != NULL) {
                strcpy(m_investorID, psz);
            } else {
                m_investorID[0] = '\0';
            }
        }

        TiXmlElement *coi = r2->FirstChildElement("CancelOrderInterval");
        if (coi != NULL) {
            const char *psz = coi->Attribute("value");
            if (psz != NULL) {
                m_nCancelOrderInterval = atoi(psz);
            }
        }

        TiXmlElement *up = r2->FirstChildElement("UserProduct");
        if (up != NULL) {
            const char *psz = up->Attribute("value");
            if (psz != NULL && strlen(psz) > 0) {
                strcpy(this->m_cUserProduct, psz);
            }
        }

        TiXmlElement *cg = r2->FirstChildElement("ConnectionGroup");
        while (cg != NULL) {
            const char *psz = cg->Attribute("name");
            const char *pszIsUdp = cg->Attribute("IsUsingUdpMd");
            if (psz != NULL) {
                list<string> *pServers = new list<string>();
                TiXmlElement *pFront = cg->FirstChildElement("TradeFront");
                while (pFront != NULL) {
                    const char *pszAddr = pFront->Attribute("Address");
                    if (pszAddr != NULL) {
                        pServers->push_back(pszAddr);
                    }
                    pFront = pFront->NextSiblingElement("TradeFront");
                }
                m_TradeServers.insert(pair<string, list<string> *>(psz, pServers));
                int usingUdp = 0;
                if (pszIsUdp != NULL && strlen(pszIsUdp) > 0) {
                    usingUdp = atoi(pszIsUdp);
                }
                this->m_UsingUDP.insert(pair<string, int>(psz, usingUdp));

                pServers = new list<string>();
                pFront = cg->FirstChildElement("MarketFront");
                while (pFront != NULL) {
                    const char *pszAddr = pFront->Attribute("Address");
                    if (pszAddr != NULL) {
                        pServers->push_back(pszAddr);
                    }
                    pFront = pFront->NextSiblingElement("MarketFront");
                }
                m_MDServers.insert(pair<string, list<string> *>(psz, pServers));

                pServers = new list<string>();
                pFront = cg->FirstChildElement("TradeQueryFront");
                while (pFront != NULL) {
                    const char *pszAddr = pFront->Attribute("Address");
                    if (pszAddr != NULL) {
                        pServers->push_back(pszAddr);
                    }
                    pFront = pFront->NextSiblingElement("TradeQueryFront");
                }
                m_TradeQueryServers.insert(pair<string, list<string> *>(psz, pServers));

                pServers = new list<string>();
                pFront = cg->FirstChildElement("TradeUdpFront");
                while (pFront != NULL) {
                    const char *pszAddr = pFront->Attribute("Address");
                    if (pszAddr != NULL) {
                        pServers->push_back(pszAddr);
                    }
                    pFront = pFront->NextSiblingElement("TradeUdpFront");
                }
                m_TradeUdpServers.insert(pair<string, list<string> *>(psz, pServers));
            }

            cg = cg->NextSiblingElement("ConnectionGroup");
        }
        doc.Clear();
    };

    int GetNextRequestID() {
        int next;
        m_lock.Lock();
        next = m_nNextRequestID++;
        m_lock.Unlock();
        return next;
    }

    void AddSecond(int seconds) {
        m_nCFFEXTime++;
        m_nSHFETime++;
        m_nDCETime++;
        m_nCZCETime++;
    }

    const char *GetBroker() {
        return m_cBroker;
    }

    const char *GetAppID() {
        return m_pszAppID;
    }
    const char *GetAuthCode() {
        return m_pszAuthCode;
    }

    const char *GetUser() {
        return m_cUser;
    }

    const char *GetUserProduct() {
        return m_cUserProduct;
    }

    void SetUser(const char *pszUser) {
        strcpy(m_cUser, pszUser);
    }

    void SetInvestorID(const char *investor) {
        strcpy(m_investorID, investor);
    }

    const char *GetInvestorID() {
        return m_investorID;
    }

    const char *GetPassword() {
        return m_cPassword;
    }

    void SetPassword(const char *pszPwd) {
        strcpy(m_cPassword, pszPwd);
    }

    const char *GetTradingDay() {
        return m_cTradingDay;
    }

    void SetTradingDay(const char *pszDay) {
        strcpy(m_cTradingDay, pszDay);
    }

    void SetMaxOrderRef(long nOrderRef) {
        m_nMaxOrderRef = nOrderRef;
    }

    void SetOrderRefFS(const char *psz) {
        strcpy(m_OrderLocalIDFS, psz);
    }

    long GetAndIncMaxOrderRef() {
        m_lockOrderRef.Lock();
        long nOrderRef = ++m_nMaxOrderRef;
        m_lockOrderRef.Unlock();

        return nOrderRef;
    }

    int GetSessionID() {
        return m_nSessionID;
    }

    void SetSessionID(int nSessionID) {
        m_nSessionID = nSessionID;
    }

    int GetFrontID() {
        return m_nFrontID;
    }

    void SetFrontID(int nFrontID) {
        m_nFrontID = nFrontID;
    }

    void SetLoginTime(const char *pszLoginTime) {
        m_nLoginTime = ToSeconds(pszLoginTime);
        strcpy(m_cLoginTime, pszLoginTime);
    }

    const char *GetLoginTime() {
        return m_cLoginTime;
    }

    void SetCFFEXTime(const char *pszTime) {
        m_nCFFEXTime = ToSeconds(pszTime);
    }

    void SetDCETime(const char *pszTime) {
        m_nDCETime = ToSeconds(pszTime);
    }

    void SetCZCETime(const char *pszTime) {
        m_nCZCETime = ToSeconds(pszTime);
    }

    void SetSHFETime(const char *pszLoginTime) {
        m_nSHFETime = ToSeconds(pszLoginTime);
    }

    int ToSeconds(const char *time) {
        if (strlen(time) < 8) {
            return 0;
        }

        char buf[5];
        int h, mi, s;
        buf[0] = time[0];
        buf[1] = time[1];
        buf[2] = '\0';
        h = atoi(buf);

        buf[0] = time[3];
        buf[1] = time[4];
        buf[2] = '\0';
        mi = atoi(buf);

        buf[0] = time[6];
        buf[1] = time[7];
        buf[2] = '\0';
        s = atoi(buf);

        return h * 3600 + mi * 60 + s;
    }

public:
    int m_nCFFEXTime;
    int m_nSHFETime;
    int m_nDCETime;
    int m_nCZCETime;
    int m_nLoginTime;

    int m_nFrontID;
    int m_nSessionID;

    int m_nCancelOrderInterval;
    char m_cUsedServers[32];

    char m_OrderLocalIDFS[12];

    char m_cDefaultPolicySO[64];
    map<string, list<string> *> m_TradeServers;
    map<string, list<string> *> m_MDServers;
    map<string, list<string> *> m_TradeQueryServers;
    map<string, list<string> *> m_TradeUdpServers;
    map<string, int> m_UsingUDP;

private:
    int m_nNextRequestID;
    CSpinLock m_lock;
    CSpinLock m_lockOrderRef;
    char m_cBroker[12];
    // new parameters
    char m_pszAppID[33];
    char m_pszAuthCode[33];

    char m_cUser[32];
    char m_cPassword[32];
    char m_cTradingDay[16];
    char m_cLoginTime[16];
    long m_nMaxOrderRef;
    char m_cUserProduct[16];

    // investorID
    char m_investorID[32];
};

#endif /* CCONFIG_H_ */
